package com.syf.config.result;

import com.alibaba.fastjson.JSONObject;
import com.syf.config.annotation.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 统一响应处理
 *
 * @author syf
 */
@ControllerAdvice  //匹配所有Controller
@Slf4j
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {

  	//从request中取出 @CommonResult注解 对象，判断是否有
	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
		CommonResult responseResultAnn = (CommonResult) RequestContextUtil.getRequest().getAttribute(ResponseResultInterceptor.RESPONSE_RESULT);
		return responseResultAnn != null ;
	}

  	//逻辑处理
  	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
		//@CommonResult注解 对象
		CommonResult responseResultAnn = (CommonResult) RequestContextUtil.getRequest().getAttribute(ResponseResultInterceptor.RESPONSE_RESULT);
		//该注解的value属性值，默认为 ResponseResult.class
		Class<? extends Result> resultClazz = responseResultAnn.value();  //临界范围

		/**
		 * isAssignableFrom()方法是从 类继承的角度去判断，instanceof关键字是从 实例继承的角度去判断
		 * isAssignableFrom()方法是判断是否为某个类的父类，instanceof关键字是判断是否某个类的子类
		 * 		父类.class.isAssignableFrom(子类.class)   //a和b为同一个类或同一个接口
		 * 		子类实例 instanceof 本身或者父类的类型
		 */
		if (resultClazz.isAssignableFrom(ResponseResult.class)) {
			//【1】全局异常返回结果
			if (body instanceof DefaultErrorResult) { //DefaultErrorResult和ResponseResult都实现了Result
				log.info("(♥◠‿◠)ﾉﾞ  全局异常处理--嗷嗷~运行出现异常啦  ლ(´ڡ`ლ)ﾞ ");
				DefaultErrorResult defaultErrorResult = (DefaultErrorResult) body;
				return ResponseResult.builder()
						.code(defaultErrorResult.getCode())
						.msg(defaultErrorResult.getMessage())
						.data(JSONObject.toJSONString(defaultErrorResult))
						.build();
			} else if (body instanceof String) {
				//【2】返回值为 String类型
				return JSONObject.toJSONString(ResponseResult.success(body));
			}

			//【3】请求Success(默认为 resultClazz = ResponseResult.class)
			return ResponseResult.success(body);
		}
		return body;
	}
}
